﻿using Newtonsoft.Json;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using UFIDA.U9.Base.BaseBE.Util;
using UFIDA.U9.CBO.Pub.Controller;
using UFSoft.UBF.Business;
using UFSoft.UBF.PL;
using UFSoft.UBF.Util.DataAccess;

namespace UFIDA.U9.Cust.YYD.PlugBE.Public
{
    public static class PublicMethod
    {
        public static string StringJoin(IEnumerable<string> args)
        {
            args = args.Distinct();
            return string.Join(",", args.Select(t => $"'{t}'"));
        }

        /// <summary>
        /// U9实体批量in条件查询
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="propName"></param>
        /// <param name="codes"></param>
        /// <returns></returns>
        public static List<T> GetDistinctElements<T>(string propName, IEnumerable<string> codes) where T : BusinessEntity
        {
            var elements = new List<T>();
            codes = codes.Distinct();
            if (codes.Any())
            {
                var finder = typeof(T).GetProperty("Finder").GetValue(null);
                var method = finder.GetType().GetMethod("FindAll", new Type[] { typeof(string), typeof(OqlParam[]) });
                string query = $"{propName} in ({StringJoin(codes)})";
                elements = ((IEnumerable)method.Invoke(finder, new object[] { query, new OqlParam[0] })).Cast<T>().ToList();
            }
            return elements;
        }
        /// <summary>
        /// DataSet转化成列表
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dataRows"></param>
        /// <returns></returns>
        public static List<T> DataRowsToList<T>(this DataRow[] dataRows) where T : new()
        {
            List<T> list = new List<T>();
            if (dataRows == null || dataRows.Length == 0)
                return list;

            var dt = dataRows[0].Table;
            var properties = typeof(T).GetProperties();
            var propertyDict = properties.ToDictionary(p => p.Name.ToUpper(), p => p);

            foreach (var row in dataRows)
            {
                T obj = new T();
                foreach (DataColumn column in dt.Columns)
                {
                    if (propertyDict.TryGetValue(column.ColumnName.ToUpper(), out PropertyInfo property))
                    {
                        if (row[column] != DBNull.Value)
                        {
                            if (property.PropertyType.IsValueType || property.PropertyType.Name == "String")
                            {
                                property.SetValue(obj, Convert.ChangeType(row[column], property.PropertyType));
                            }
                        }
                        else
                        {
                            property.SetValue(obj, null);
                        }
                    }
                }
                list.Add(obj);
            }
            return list;
        }
        public static List<T> DataRowsToList<T>(this DataRowCollection dataRows) where T : new()
        {
            return dataRows.Cast<DataRow>().ToArray().DataRowsToList<T>();
        }
        /// <summary>
        /// 字符串转decimal，失败返回默认值
        /// </summary>
        /// <param name="number"></param>
        /// <param name="defaultVal"></param>
        /// <returns></returns>
        public static decimal TrtParseToDecimal(this string number, decimal defaultVal = 0)
        {
            try
            {
                return decimal.Parse(number);
            }
            catch
            {
                return defaultVal;
            }
        }

        /// <summary>
        /// 获取值集扩展字段
        /// </summary>
        /// <typeparam name="T">实体</typeparam>
        /// <param name="fieldName">示例:nameof(so.DescFlexField.PrivateDescSeg1)或直接PrivateDescSeg1</param>
        /// <returns></returns>
        public static Dictionary<string, string> GetDescFlexField<T>(string fieldName) where T : BusinessEntity
        {
            Dictionary<string, string> result = new Dictionary<string, string>();
            string entityFullName = typeof(T).FullName;
            string contextType;
            string num;
            if (fieldName.Contains("PrivateDescSeg"))
            {
                contextType = "Global";
            }
            else if (fieldName.Contains("PubDescSeg"))
            {
                contextType = "Public";
            }
            else
            {
                return result;
            }
            var match = Regex.Match(fieldName, @"\d+"); // 匹配数字
            if (match.Success)
            {
                num = match.Value;
            }
            else
            {
                return result;
            }
            string sql = $@"
select e.Code,f.Name
from Base_DescFlexSegment a
inner join Base_DescFlexContext b on a.DescFlexContext = b.ID and b.ContextValue = '{contextType}' and a.Number = {num}
inner join Base_DescFlexFieldDef c on b.DescFlexFieldDef = c.ID
inner join UBF_MD_Class d on c.EntityType = d.Local_ID
inner join Base_DefineValue e on a.ValueSetDef = e.ValueSetDef
inner join Base_DefineValue_Trl f on e.ID = f.ID and f.SysMLFlag = 'zh-CN'
where d.FullName = '{entityFullName}'
";
            DataAccessor.RunSQL(DataAccessor.GetConn(), sql, null, out DataSet ds);
            foreach (DataRow row in ds.Tables[0].Rows)
            {
                if (!result.ContainsValue(row["Code"].ToString()))
                {
                    result.Add(row["Code"].ToString(), row["Name"].ToString());
                }
            }
            return result;
        }
        /// <summary>
        /// 获取自定义枚举信息
        /// </summary>
        /// <param name="fullName"></param>
        /// <returns></returns>
        public static List<ExtEnum> GetExtEnums(string fullName)
        {
            string sql = $@"
SELECT  A.EValue [Value]
       ,A.Code
       ,B.Name
FROM dbo.UBF_Sys_ExtEnumValue A
INNER JOIN UBF_Sys_ExtEnumValue_Trl B
ON A.ID = b.ID
WHERE ExtEnumType = (
SELECT  id
FROM dbo.UBF_Sys_ExtEnumType
WHERE Code = '{fullName}' )
";
            DataAccessor.RunSQL(DataAccessor.GetConn(), sql, null, out DataSet ds);
            List<ExtEnum> result = DataRowsToList<ExtEnum>(ds.Tables[0].Rows);
            return result;
        }

        public static string ToJson(this string s)
        {
            return JsonConvert.ToString(s).Trim('"').Replace("\n", " ");
        }

        /// <summary>
        /// 获取枚举显示名称
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t">直接传枚举，如：itemmaster.ItemFormAttribute</param>
        /// <returns></returns>
        public static string GetSysEnumName<T>(T t)
        {
            var properties = typeof(T).GetProperties();
            var valueProp = properties.FirstOrDefault(u => u.Name == "Value");
            string result = "";
            if (valueProp != null)
            {
                result = GetEnumName.RunFunc(typeof(T).FullName, valueProp.GetValue(t).ToString
    (), "zh-cn");
            }
            return result;
        }
        /// <summary>
        /// 简洁执行sql
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public static DataSet RunSQL(string sql)
        {
            DataAccessor.RunSQL(DataAccessor.GetConn(), sql, null, out DataSet ds);
            return ds;
        }

    }
    public class ExtEnum
    {
        public int Value { get; set; }
        public string Code { get; set; }
        public string Name { get; set; }
    }
}
